#include "string.h"
#include <iostream>
using namespace std;

void show(int arr[], int size);
void getarr(int arr[]);

// 逐字节拷贝
void* my_memcpy_byte(void* dst, const void* src, int n){
    if(dst == nullptr && src == nullptr && n < 0) return nullptr;

    char* psrc = (char*) src;
    char* pdst = (char*) dst;
    if(pdst > psrc && pdst < psrc + n){ // 考虑写覆盖
        pdst = pdst + n - 1;
        psrc = psrc + n - 1;
        while(n--) *pdst-- = *psrc--;
    }
    else{
        while(n--) *pdst++ = *psrc++;
    }
    return dst;
}

// 4 字节拷贝
void* my_memcpy_int(void* dst, void* src, int n){
    if(dst == nullptr || src == nullptr || n < 0) return nullptr;

    int* pdst = (int*) dst;
    int* psrc = (int*) src;
    char* tmp1 = nullptr;
    char* tmp2 = nullptr;
    int c1 = n / 4;
    int c2 = n % 4;

    if(pdst > psrc && (char*)pdst < (char*)psrc + n){
        tmp1 = (char*)pdst + n - 1;
        tmp2 = (char*)psrc + n - 1;
        while(c2--) *tmp1-- = *tmp2--;

        ++tmp1, ++tmp2;
        pdst = (int*) tmp1;
        psrc = (int*) tmp2;
        pdst--, psrc--;
        while(c1--) *pdst-- = *psrc--;

    }
    else{
        while(c1--) *pdst++ = *psrc++;
        tmp1 = (char*)pdst;
        tmp2 = (char*)psrc;
        while(c2--) *tmp1++ = *tmp2++;
    }
    return dst;
}

// https://www.cnblogs.com/chuanfengzhang/p/8447251.html
int main(int argc, char const *argv[])
{
    int arr[10], arr2[10], arr3[10];

    getarr(arr);
    show(arr, 10);
    my_memcpy_byte(arr, arr + 2, 4 * sizeof(int));
    show(arr, 10);

    getarr(arr);
    my_memcpy_byte(arr3, arr, 10 * sizeof(int));
    show(arr3, 10);

    getarr(arr);
    my_memcpy_byte(arr + 2, arr, 4 * sizeof(int));
    show(arr, 10);

    cout << endl;

    getarr(arr);
    show(arr, 10);
    my_memcpy_int(arr, arr + 2, 4 * sizeof(int));
    show(arr, 10);

    getarr(arr);
    my_memcpy_int(arr3, arr, 10 * sizeof(int));
    show(arr3, 10);

    getarr(arr);
    my_memcpy_int(arr + 2, arr, 4 * sizeof(int));
    show(arr, 10);

    return 0;
}


void show(int arr[], int size){
    for(int i = 0; i < size; ++i){
        cout << arr[i] << " ";
    }
    cout << endl;
}

void getarr(int arr[]){
    for(int i = 0; i < 10; ++i)
        arr[i] = i;
}